<?php
/**
 * Created by PhpStorm.
 * User: MF
 * Date: 2018/7/1
 * Time: 22:02
 */


// 通过反射类能搞很多事情，比如根据class名称自动实例化
// 反射API的功能显然更强大，甚至能还原这个类的原型，包括方法的访问权限
// 动态实例化对象

// https://blog.csdn.net/lmjy102/article/details/71711313?locationNum=6&fps=1


class Object {

	public function __construct($config=[])
	{
		if (isset($config['name']))
			echo $config['name'];
	}

}

/**
 *
 * Class Person
 */
class Person extends Object{

	private $_name;

	private $age;

	public function setName($name) {
		$this->_name = $name;
	}

	public function getName() {
		return $this->_name;
	}

	public function say() {
		echo 'hello';
	}
}



class Container {

	/**
	 * @var array singleton objects indexed by their types
	 */
	private $_singletons = [];
	/**
	 * @var array object definitions indexed by their types
	 */
	private $_definitions = [];
	/**
	 * @var array constructor parameters indexed by object types
	 */
	private $_params = [];
	/**
	 * @var array cached ReflectionClass objects indexed by class/interface names
	 */
	private $_reflections = [];
	/**
	 * @var array cached dependencies indexed by class/interface names. Each class name
	 * is associated with a list of constructor parameter types or default values.
	 */
	private $_dependencies = [];

	/**
	 * 根据类名把所依赖的构造函数中的参数全提取并缓存起来
	 * @param $class
	 * @return array
	 */
	protected function getDependencies($class)
	{
		if (isset($this->_reflections[$class])) {
			return [$this->_reflections[$class], $this->_dependencies[$class]];
		}

		$dependencies = [];
		$reflection = new ReflectionClass($class);

		$constructor = $reflection->getConstructor();
		if ($constructor !== null) {
			foreach ($constructor->getParameters() as $param) {
				if ($param->isDefaultValueAvailable()) {
					$dependencies[] = $param->getDefaultValue();
				} else {
					// $c = $param->getClass();
					// $dependencies[] = Instance::of($c === null ? null : $c->getName());
				}
			}
		}

		$this->_reflections[$class] = $reflection;
		$this->_dependencies[$class] = $dependencies;

		return [$reflection, $dependencies];
	}
}

// 建立 Person这个类的反射类
$reflection = new ReflectionClass('Person');

$constructor = $reflection->getConstructor();

print_r($constructor);

print_r($constructor->getParameters());

$obj = $reflection->newInstance();

// hello
$obj->say();

// 相当于实例化Person 类
// $instance = $class->newInstanceArgs($args);

$properties = $reflection->getProperties();

print_r($properties);